/*
 * allele.h
 *
 *  Created on: Jul 30, 2010
 *      Author: Pierre Lindenbaum PhD
 *              plindenbaum@yahoo.fr
 *              http://plindenbaum.blogspot.com
 *              
 */

#ifndef ALLELE_H_
#define ALLELE_H_

class Allele
    {
    private:
	const IndividualPtr _individual;
	char _base;
    public:
	Allele(const IndividualPtr individual,char base):
	   _individual(individual),
	   _base(base)
	    {
	    }

	Allele(const Allele& cp):_individual(cp._individual),_base(cp._base)
	    {
	    }

	virtual ~Allele()
	    {
	    }

	const IndividualPtr _individual() const
	    {
	    return _individual;
	    }

	char base() const
	    {
	    return _base;
	    }

    friend std::ostream& operator << (std::ostream& out,const Allele& o);
    };

 std::ostream& operator << (std::ostream& out,const Allele& o)
    {
     out << *(o.individual()) << "("<< *(o.base()) << ")";
    return out;
    }


 class AllelePair
     {
     private:
	Allele a0;
	Allele a1;
     public:
 	AllelePair(
 		const IndividualPtr i0,char base0,
 		const IndividualPtr i1,char base1
 		):a0(i0,base0),a1(i1,base1)
 	    {
 	    }

 	AllelePair(
 		const Allele a0,
 		const Allele a1
 		):a0(a0),a1(a1)
 	    {
 	    }

 	AllelePair(const AllelePair& cp):a0(cp.a0),a1(cp.a1)
 	    {
 	    }

 	virtual ~AllelePair()
 	    {
 	    }

 	const IndividualPtr individual(int side) const
 	    {
 	    return (side==0?a0.individual():a1.individual());
 	    }

 	char base(int side) const
 	    {
 	    return (side==0?a0.base():a1.base());
 	    }

 	AllelePair swap() const
	    {
 	    return AllelePair(a1,a0);
	    }

     friend std::ostream& operator << (std::ostream& out,const AllelePair& o);
     };

 std::ostream& operator << (std::ostream& out,const AllelePair& o)
    {
     out << "[" << o.a0 <<"/" << o.a1 << "]";
    return out;
    }

 class Genotype:public AllelePair
     {
     private:
	  const MarkerPtr _marker;
     public:
	 Genotype(
		 const MarkerPtr marker,
		 const IndividualPtr i0,char base0,
	 	 const IndividualPtr i1,char base1):AllelePair(i0,base0,i1,base1),_marker(marker)
	     {
	     }
	 Genotype(
	 		 const MarkerPtr marker,
	 		 AllelePair pair):AllelePair(pair),_marker(marker)
			{
	 	     }
	~Genotype()
	    {
	    }

	 const MarkerPtr marker()
	     {
	     return _marker;
	     }

     };


#endif /* ALLELE_H_ */
